The flatpages app
Django comes with an optional "flatpages" application. It lets you store simple "flat" HTML content in a database and handles the management for you.
A flatpage is a simple object with a URL, title and content. Use it for one-off, special-case pages, such as "About" or "Privacy Policy" pages, that you want to store in a database but for which you don't want to develop a custom Django application.
A flatpage can use a custom template or a default, systemwide flatpage template. It can be associated with one, or multiple, sites.
Here are some examples of flatpages on Django-powered sites:
Installation
To install the flatpages app, follow these two steps:
- Add "django.contrib.flatpages" to your INSTALLED_APPS setting.
- Add "django.contrib.flatpages.middleware.FlatpageFallbackMiddleware" to your MIDDLEWARE_CLASSES setting.
- Run the command django-admin.py install flatpages.
How it works
django-admin.py install flatpages creates two tables in your database: django_flatpages and django_flatpages_sites. django_flatpages is a simple lookup table that essentially maps a URL to a title and bunch of text content. django_flatpages_sites associates a flatpage with a site.
The FlatpageFallbackMiddleware does all of the work. Each time any Django application raises a 404 error, this middleware checks the flatpages database for the requested URL as a last resort. Specifically, it checks for a flatpage with the given URL with a site ID that corresponds to the SITE_ID setting.
If it finds a match, it follows this algorithm:
- If the flatpage has a custom template, it loads that template. Otherwise, it loads the template flatpages/default.
- It passes that template a single context variable, flatpage, which is the flatpage object. It uses DjangoContext in rendering the template.
If it doesn't find a match, the request continues to be processed as usual.
The middleware only gets activated for 404s -- not for 500s or responses of any other status code.
Note that the order of MIDDLEWARE_CLASSES matters. Generally, you can put FlatpageFallbackMiddleware at the end of the list, because it's a last resort.
For more on middleware, read the middleware docs.
How to add, change and delete flatpages
Via the admin interface
If you've activated the automatic Django admin interface, you should see a "Flatpages" section on the admin index page. Edit flatpages as you edit any other object in the system.
Via the Python API
Flatpages are represented by a standard Django model, which lives in django/contrib/flatpages/models/flatpages.py. You can access flatpage objects via the Django database API.
Flatpage templates
By default, flatpages are rendered via the template flatpages/default, but you can override that for a particular flatpage.
Creating the flatpages/default template is your responsibility; in your template directory, just create a flatpages directory containing a file default.html.
Flatpage templates are passed a single context variable, flatpage, which is the flatpage object.
Here's a sample flatpages/default template:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
"http://www.w3.org/TR/REC-html40/loose.dtd">
<html>
<head>
<title>{{ flatpage.title }}</title>
</head>
<body>
{{ flatpage.content }}
</body>
</html>
Comments
pbx November 11, 2005 at 8:40 a.m.
That's cool. You could even make it conditional -- a "process with Markdown" boolean field for example -- so that you could still use HTML in cases where you really needed to, but use your favored markup everywhere else.
Lukas November 12, 2005 at 2:21 p.m.
Does this really render a complete 404-page and throws it away when finding that there is a flatpage for that particular url? Looks like a bit of overhead to me, although I have no idea what that really costs.
--
Lukas
Simon Willison November 12, 2005 at 2:27 p.m.
Lukas: Not at all. The decision to serve a flat page is made before the 404 handler (and subsequent page rendering). The only overhead is an additional check for a possible flat page every time your site has a 404 error - and on well designed sites that shouldn't happen wery often at all anyway.
Steve November 21, 2005 at 2:36 p.m.
How exactly does the "Enable comments" option work? I didn't see any added functionality just by enabling it, and can't find any documentation on it. Am I missing something obvious?
Post a comment
Note: Please only use the comments for questions/critcisms/suggestions on the docs; if you experience errors please file a ticket, ask in the IRC channel, or post to the django-users list. Comments will be periodically reviewed, integrated into the documentation proper, and removed.

Simon Willison November 11, 2005 at 12:28 a.m.
One useful thing you can do with flatpages is use a markup processing filter of some sort in your template, for example:
{% load markup %}
{{ flatpage.content|textile }}
You can now use textile formatting on your flatpage (or markdown or ReStructuredText).